
/**
 * 这个正则表达式用于匹配 JavaScript 错误栈中的堆栈跟踪信息中的单个条目，其中包含文件名、行号和列号等信息。
 * 具体来说，它匹配以下格式的文本：
 * at functionName (filename:lineNumber:columnNumber)
 * at filename:lineNumber:columnNumber
 * at http://example.com/filename:lineNumber:columnNumber
 * at https://example.com/filename:lineNumber:columnNumber
 */
const FULL_MATCH =
  /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;

// 要提取几行错误信息
const STACK_TRACE_LIMIT = 3;

// 通过正则表达式解析一行的错误信息
// line 就是字符串, 按照一定格式写出来的错误信息
// 利用正则表达式从字符串 line 中提取出: filename, functionName, lineno, colno
function getError(line) { 
  const lineMatch = line.match(FULL_MATCH);
  if (!lineMatch) return {};

  return {
    functionName: lineMatch[1] || '',
    filename: lineMatch[2] || '<anonymous>',
    lineno: parseInt(lineMatch[3], 10) || undefined,
    colno: parseInt(lineMatch[4], 10) || undefined
  }
}

//解析错误堆栈
// stack 就是字符串, 按照一定格式写出来的错误信息
// const errInfo0 = 'Cannot read properties of null (reading "length") '
// const errInfo1 = 'at Page2.vue:24:20 '
// const errInfo2 = 'at mounted (Page2.vue:20:3) '
// const stack = `${errInfo0}/n ${errInfo1}/n ${errInfo2}/n `
export function getErrors(stack) { 
  //如果没有stack直接返回[]
  if (!stack) return [];
  const lines = getStackArr(stack)
  return lines.map(line => getError(line))
} 

// 字符串转数组: 以'/n'为分割将字符串变成数组
// stack = `
//   TypeError: Cannot read properties of null (reading 'length') /n
//   at Page2.vue:24:20 /n
//   at mounted (Page2.vue:20:3) /n
// `
// 
// return = [
//   TypeError: Cannot read properties of null (reading 'length'),
//   at Page2.vue:24:20,
//   at mounted (Page2.vue:20:3),
// ]
function getStackArr(stack) {
  const lines = stack.split('\n')
  // [
  //    "第0行 error: TypeError: Cannot read properties of null (reading 'length')",
  //    "第1行 error: at Page2.vue:24:20",
  //    "第2行 error: at mounted (Page2.vue:20:3)",
  //    "第3行 error: ...",
  //    "第4行 error: ...",
  // ]
  return lines.splice(1, STACK_TRACE_LIMIT) // 只提取一部分错误信息
}